import { connect } from "node:tls";
import "./css/main.css";
import * as signalR from "@microsoft/signalr";
import * as msgpack from "@microsoft/signalr-protocol-msgpack";

const divMessages: HTMLDivElement = document.querySelector("#divMessages");
const tbMessage: HTMLInputElement = document.querySelector("#tbMessage");
const btnSend: HTMLButtonElement = document.querySelector("#btnSend");
const getMsg: HTMLButtonElement = document.querySelector("#getMsg");
const currentTime: HTMLDivElement = document.querySelector("#currentTime");

const userName = new Date().getTime();

const url = "https://localhost:51541";

// 使用 stream 
const connection4 = new signalR.HubConnectionBuilder()
    .withUrl(url + "/hubs/streaming", { skipNegotiation: true, transport: signalR.HttpTransportType.WebSockets })
    //.withHubProtocol(new msgpack.MessagePackHubProtocol())
    .withAutomaticReconnect([0, 2000, 10000, 30000]) // 自动重连策略
    .build();
//connection4.start();

// 需要使用异步方法启动 但是我们还想让他立即执行，所以使用立即执行函数
(async () => {
    try {
        await connection4.start();
    } catch (e) {
        console.error(e.toString());
    }
})();


const loginToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoid2phQG1pY3Jvc29mdC5jb20iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbiIsIkN1c3RvbUNsYWltIjoiQ3VzdG9tVmFsdWUiLCJleHAiOjE3NDgzNTIwNzksImlzcyI6IndqYSIsImF1ZCI6IndqYSJ9.6ONpM5f-ZAo0Ve-nRO2F5k78f1aCMRKuZOcK8eoMcJg";

const connection3 = new signalR.HubConnectionBuilder().withUrl(url + "/hubs/authorized", { accessTokenFactory: () => loginToken }).build();
connection3.start().catch((err) => console.error(err));

const connection2 = new signalR.HubConnectionBuilder().withUrl(url + "/hubs/clock").build();

// 服务器给客户端发送消息 时间是字符串格式
connection2.on("ShowTime", (time: string) => {
    //console.log("ShowTime", time);
    //console.log(typeof time);
    //var t = new Date(time);
    //currentTime.innerText = "  "+ t.toLocaleDateString()+" " +t.toLocaleTimeString();
    currentTime.innerText = time;
});

connection2.start().then(() => {
    console.log("Clock Hub started");
})
    .catch((err) => console.error(err));

const connection = new signalR.HubConnectionBuilder()
    .withUrl(url + "/hub")
    .withHubProtocol(new msgpack.MessagePackHubProtocol()) // 使用 MessagePack 协议
    .build();

connection.on("ReceiveMessage", (username: string, message: string) => {
    console.log(username, message);
    let messages = document.createElement("div");

    messages.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`;

    divMessages.appendChild(messages);
    divMessages.scrollTop = divMessages.scrollHeight;
});

// 服务器给客户端发送消息
connection.on("ReceiveMessage", (req) => {
    console.log("ReceiveMessage", req);
});

// 客户端给服务器发送消息
connection.on("GetMessage", async () => {
    let promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("ok 来自客户端的消息");
        }, 100);
    });
    return promise;
});

connection.start().catch((err) => document.write(err));

tbMessage.addEventListener("keyup", (e: KeyboardEvent) => {
    if (e.key === "Enter") {
        send();
    }
});

btnSend.addEventListener("click", send);

function send() {
    //connection.invoke("GetTotalLength", { parm1: "msg" })
    connection3.invoke("TestAuthorization");
    connection3.invoke("banUser", "wja");

    try {
        // 可以调用 CounterChannel 和 Counter 两个方法
        connection4.stream("CounterChannel", 10, 500)
            .subscribe({
                next: (item: number) => {
                    console.log("Counter item:", item);
                    let messages = document.createElement("div");
                    messages.innerHTML = `<div class="message-author">Counter</div><div>${item}</div>`;
                    divMessages.appendChild(messages);
                    divMessages.scrollTop = divMessages.scrollHeight;
                },
                complete: () => {
                    console.log("Counter stream completed")
                    let messages = document.createElement("div");
                    messages.innerHTML = `<div class="message-author">Counter</div><div>Stream completed</div>`;
                    divMessages.appendChild(messages);
                },
                error: (err) => {
                    console.error("Counter stream error:", err)
                    let messages = document.createElement("div");
                    messages.innerHTML = `<div class="message-author">Counter</div><div>Error: ${err}</div>`;
                    divMessages.appendChild(messages);
                }
            })
    } catch (e) {
        console.error(e.toString());
    }
   

    connection.invoke("SendMessage", { UserName: userName, Message: tbMessage.value }).then(() => (tbMessage.value = ""));
}

getMsg.addEventListener("click", async () => {
    //connection.send("WaitForMessage");
    //connection.invoke("GetTotalLength", { parm1: "msg", parm2: "value" })

    //connection.invoke("Broadcast", "msg")

    //connection.invoke("SendMessage", "async", "username", "async", "void");

    // 测试stream 上传数据到服务器
    const subject = new signalR.Subject();
    await connection4.send("UploadStream", subject);
    var iteration = 0;
    const intervalHandler = setInterval(() => {
        iteration++;
        subject.next(iteration.toString());
        if (iteration >= 10) {
            subject.complete();
            clearInterval(intervalHandler);
        }
    }, 1000);

    // 异常处理
    //try {
    //    connection.invoke("GetMessage", username,"msg")
    //} catch (err) {
    //    console.error(err);
    //}
});
